
import matplotlib.pyplot as plt


colors=['darkorange','blue','limegreen','deeppink','green','black']
#点标记的样式 ^表示三角形，*五角星，o圆点，3箭头
markers=['s-','o-','x-','d-','^-','p-']
scale = [0, 2, 4, 7, 12]
figsize=[6,5]
dpi=300
fontsize=12
linewidth=2.7
markersize=12

def draw(wtList:list[int],filename:str):
    numDict = {}
    timeDict = {}
    memoryDict = {}
    method = ''
    with open(filename,"r",encoding="utf-8") as f:
        for item in f.readlines():
            items = item.split(" ")
            if method != items[0]:
                method = items[0]
                numDict.update({method:[float(items[1])]})
                timeDict.update({method:[float(items[2])]})
                memoryDict.update({method:[float(items[3])]})
            else:
                numDict[method].append(float(items[1]))
                timeDict[method].append(float(items[2]))
                memoryDict[method].append(float(items[3]))
    drawNum(numDict,wtList)
    drawTime(timeDict,wtList)
    drawMemory(memoryDict,wtList)


def drawNum(numDict:dict,idx:list[int]):
    plt.figure(figsize=(figsize[0], figsize[1]), dpi=dpi)
    plt.xlabel('$\epsilon$', fontsize=fontsize+6)  # x轴标题
    plt.ylabel('Utility', fontsize=fontsize+6)  # y轴标题
    plt.tick_params(labelsize=fontsize)
    plt.rcParams.update({'font.size':fontsize+2})#设置图例的字体大小

    # 自定义横坐标的刻度
    # scale = np.arange(len(idx))
    plt.xticks(scale, idx)
    plt.yticks(rotation=60)
    colorNum = 0
    itemName = []
    for item in numDict:
        # if item == 'OPT':
        #     colorNum+=1
        #     continue
        itemName.append(item)
        plt.plot(scale, numDict[item], markers[colorNum], color=colors[colorNum], linewidth=linewidth,
                 markersize=markersize,
                 markerfacecolor='none')
        colorNum += 1
    plt.legend(itemName)  # 设置折线名称
    # plt.show()
    plt.savefig("picture/wtEpsilon.png")
    print("Num")
    multiple = {}
    for j in numDict:
        temp=0
        nu = 0
        for k in numDict[j]:
            temp += k
            nu+=1
        temp = temp/nu
        multiple.update({j:temp})
    print(multiple)
    ETGOA = multiple["KS"]
    for item in multiple:
        re = ETGOA/multiple[item]
        print("KS up",item,":\t",str(round(re,2)))

def drawTime(timeDict:dict,idx:list[int]):
    plt.figure(figsize=(figsize[0], figsize[1]), dpi=dpi)
    plt.xlabel('$\epsilon$', fontsize=fontsize+6)  # x轴标题
    plt.ylabel('Time(secs)', fontsize=fontsize+6)  # y轴标题
    plt.tick_params(labelsize=fontsize)
    plt.rcParams.update({'font.size':fontsize+2})#设置图例的字体大小

    # 自定义横坐标的刻度
    # scale = np.arange(len(idx))
    plt.xticks(scale, idx)
    plt.yticks(rotation=60)
    colorNum = 0
    itemName = []
    for item in timeDict:
        # if item == 'OPT':
        #     colorNum+=1
        #     continue
        itemName.append(item)
        plt.plot(scale, timeDict[item], markers[colorNum], color=colors[colorNum], linewidth=linewidth,
                 markersize=markersize,
                 markerfacecolor='none')
        colorNum += 1
    plt.legend(itemName,loc="upper right",bbox_to_anchor=(1,0.6))  # 设置折线名称
    # plt.show()
    plt.savefig("picture/wtEpsilonTime.png")
    print("Time")
    multiple = {}
    for j in timeDict:
        temp=0
        nu = 0
        for k in timeDict[j]:
            temp += k
            nu+=1
        temp = temp/nu
        multiple.update({j:temp})
    print(multiple)
    ETGOA = multiple["KS"]
    for item in multiple:
        re = multiple[item]/ETGOA
        print("KS up",item,":\t",str(round(re,2)))

def drawMemory(memoryDict:dict,idx:list[int]):
    plt.figure(figsize=(figsize[0], figsize[1]), dpi=dpi)
    plt.xlabel('$\epsilon$', fontsize=fontsize+6)  # x轴标题
    plt.ylabel('Memory(KB)', fontsize=fontsize+6)  # y轴标题
    plt.tick_params(labelsize=fontsize)
    plt.rcParams.update({'font.size':fontsize+2})#设置图例的字体大小

    # 自定义横坐标的刻度
    # scale = np.arange(len(idx))
    plt.xticks(scale, idx)
    # plt.yticks(rotation=60)

    #科学计数坐标
    ax = plt.gca()
    ax.ticklabel_format(style='sci', scilimits=(-1, 2), axis='y', useMathText=True)
    ax.get_yaxis().get_offset_text().set(va='bottom', ha='left')
    ax.yaxis.get_offset_text().set_fontsize(fontsize)

    colorNum = 0
    itemName = []
    for item in memoryDict:
        # if item == 'OPT':
        #     colorNum += 1
        #     continue
        itemName.append(item)
        plt.plot(scale, memoryDict[item], markers[colorNum], color=colors[colorNum], linewidth=linewidth,
                 markersize=markersize,
                 markerfacecolor='none')
        colorNum += 1
    plt.legend(itemName,loc="upper right",bbox_to_anchor=(1,0.95))  # 设置折线名称
    # plt.show()
    plt.savefig("picture/wtEpsilonMemory.png")
    plt.close()
    #计算不同方法倍数关系
    print("Momery")
    multiple = {}
    for j in memoryDict:
        temp=0
        nu = 0
        for k in memoryDict[j]:
            temp += k
            nu+=1
        temp = temp/nu
        multiple.update({j:temp})
    print(multiple)
    BGOA = multiple["GS"]
    for item in multiple:
        re = (multiple[item]-BGOA)/multiple[item]
        print("GS down",item,":\t",str(round(re*100,2)),"%")

if __name__ =="__main__":
    wtList = [0.1, 0.4, 0.6, 1.25, 2.5]
    fileName = "resultData/epsilon.txt"
    draw(wtList,fileName)